/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.yonsei.iwb.ts.model;


import com.hp.hpl.jena.rdf.model.InfModel;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.ResourceFactory;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.reasoner.Reasoner;
import com.hp.hpl.jena.reasoner.ReasonerRegistry;
import com.hp.hpl.jena.reasoner.rulesys.GenericRuleReasonerFactory;
import com.hp.hpl.jena.tdb.TDBFactory;
import com.hp.hpl.jena.util.FileManager;
import com.hp.hpl.jena.vocabulary.OWL;
import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.RDFS;
import com.hp.hpl.jena.vocabulary.ReasonerVocabulary;

import java.io.InputStream;
import java.util.Vector;

/**
 *
 * @author dk
 */
public class JenaModel {       

    public static int NUMBER_OF_PATH = 1;
    private Model model;
    
    private int ontType = JenaModelType.MEMORY_MODEL;    
        
    public JenaModel(int type) {
        this.ontType = type;
        if (type == JenaModelType.MEMORY_MODEL) {
            this.model = ModelFactory.createDefaultModel();
        } else if (type == JenaModelType.TDB_MODEL) {
            this.model = TDBFactory.createModel(JenaModelType.MODEL_DIR);
        }
    }

    public void loadOntology(String fileName) {
        if(this.ontType == JenaModelType.TDB_MODEL) {
            this.model.removeAll();
        }
        InputStream in = FileManager.get().open(fileName);
        this.model.read(in, null);
        
        
        
//        Resource configuration =  model.createResource();
//        configuration.addProperty(ReasonerVocabulary.PROPruleMode, "forward");
//        configuration.addProperty(ReasonerVocabulary.PROPruleSet,  JenaModelType.INFERENCE_RULE_FILE);        
//        Reasoner reasoner = GenericRuleReasonerFactory.theInstance().create(configuration);
//        InfModel genInfmodel = ModelFactory.createInfModel(reasoner, model);
//        this.model.add(genInfmodel.getDeductionsModel());
        
//        Reasoner owlReasoner = ReasonerRegistry.getOWLMiniReasoner();
//        InfModel owlInfmodel = ModelFactory.createInfModel(owlReasoner, model);
//        this.model.add(owlInfmodel);
        
        Reasoner rdfsReasoner = ReasonerRegistry.getRDFSReasoner();
        InfModel rdfsInfmodel = ModelFactory.createInfModel(rdfsReasoner, model);
        this.model.add(rdfsInfmodel);
                
//        this.refineJenaModel();
        if (this.ontType == JenaModelType.TDB_MODEL) {
            model.close();
        }
    }    

//    public int getResourceType(Resource r) {
//        StmtIterator si = model.listStatements(r, RDF.type, (RDFNode) null);
//        if (si.hasNext()) {
//            RDFNode object = si.nextStatement().getObject();
//            if (object.equals(OWL.Class) || object.equals(RDFS.Class)) {
//                return JenaResourceType.CLASS;
//            } else if (object.equals(OWL.ObjectProperty) || object.equals(OWL.DatatypeProperty) || object.equals(RDF.Property)) {
//                return JenaResourceType.PROPERTY;
//            }
//            return JenaResourceType.INSTANCE;
//        } else {
//            return JenaResourceType.UNDECLARED;
//        }
//    }

    public Model getJenaModel() {
        if (this.ontType == JenaModelType.TDB_MODEL) {
            this.model = TDBFactory.createModel(JenaModelType.MODEL_DIR);
        }        
        return this.model;
    }   
    
    private void refineJenaModel() {
        if (this.ontType == JenaModelType.TDB_MODEL) {
            this.model = TDBFactory.createModel(JenaModelType.MODEL_DIR);
        }
        Vector<Property> p = new Vector<Property>();
        StmtIterator st = this.model.listStatements(null, RDF.type, OWL.DatatypeProperty);
        while(st.hasNext()){
            Property datatype = st.nextStatement().getSubject().as(Property.class);
            p.add(datatype); 
        }
        Property isDummy = this.model.createProperty("http://iweb.yonsei.ac.kr/ontologies/smarttv/isDummy");
        Property hasUUID = this.model.createProperty("http://iweb.yonsei.ac.kr/ontologies/smarttv/hasUUID");
        Property initDate = this.model.createProperty("http://iweb.yonsei.ac.kr/ontologies/smarttv/film/film__initial_release_date");
                
        p.remove(isDummy);
        p.remove(hasUUID);
        p.remove(initDate);
        
        for (int i = 0; i < p.size(); i++) {
            this.model.removeAll(null, p.get(i), (RDFNode) null);
            this.model.removeAll(p.get(i), RDF.type, OWL.DatatypeProperty);
            this.model.removeAll(p.get(i), RDFS.domain, (RDFNode) null);
            this.model.removeAll(p.get(i), RDFS.range, (RDFNode) null);
            this.model.removeAll(p.get(i), RDFS.label, (RDFNode) null);
        }        
        
//        this.model.removeAll(OWL.Nothing, RDFS.subClassOf, (RDFNode) null);                
//        return this.model;
    }
   
}
